#include "normSnort.hpp"
/** \fn normSnort()
    \brief normaliser constructor for snort library
    \param void
    \return normSnort object
    */
normSnort::normSnort()
{
    using namespace std;
    /*The regular expression*/
    /*RE date*/
    string dt="([a-zA-Z]{3}\\s*[0-9]{1,2})";
    /*RE time*/
    string ts="([0-9]{2,2}[:,;][0-9]{2,2}[:,;][0-9]{2,2})";
    /*RE any word*/
    string word="(\\w+)";
    /*RE process ID*/
    string pid="\\[(\\d+)\\]";
    /*RE generator*/
    string generator="(\\d+)";
    /*RE signature id. Its same as generator because basically they both are numbers.The only difference is the position
     * of occurence*/
    string sigid=generator;
    /*RE signature version*/
    string sigv=generator;
    /*RE protocol*/
    string protocol="\\{([A-Z]{3})\\}";
    /*RE source-ip destination-ip*/
    string sipDip="(\\s+((\\d+\\.){3}\\d+):(\\d+))\\s*\\->\\s*((((\\d+\\.){3})\\d+):(\\d+))";
    /*RE complete basic which includes date, timestamp, processID, generator, signatureID, signature version*/
    string basic=dt+"\\s*"+ts+"\\s*"+word+"\\s*"+word+pid+":\\s*\\["+generator+":"+sigid+":"+sigv+"\\]";
    /*Compile RE basic*/
    b=boost::regex(basic);
    /*Compile RE for protocol*/
    p=boost::regex(protocol);
    /*Compile RE for source-ip destination-ip*/
    i=boost::regex(sipDip);
}
/** \fn void normSnort(string,regex)
    \brief extract the basic content using basic RE
    \param string &input The log string
    \param regex &e basic RE
    \return void
    * Postcondition: the BSONObj is updated with the basic details
    */
void normSnort::normalize_basic(std::string &input,boost::regex &e)
{
    using namespace std;
    boost::match_results<std::string::const_iterator> what;
    /*No match?*/
    if(0 == boost::regex_search(input, what, e,boost::match_default | boost::match_partial))
    {
      return;
    }
    /*Matched*/
    if(what[0].matched && (what.size()==9))
    {
        x.append("Date",string(what[1].first,what[1].second));
        x.append("Time",string(what[2].first,what[2].second));
        x.append("Process",string(what[4].first,what[4].second));
        x.append("Generator",string(what[5].first,what[5].second));
        x.append("SignatureID",string(what[6].first,what[6].second));
        x.append("SignatureVer",string(what[7].first,what[7].second));
    }   
}
/** \fn void normalize_ip(string,regex)
    \brief Extract source-ip destination-ip
    \param string &input The log string
    \param regex the sipdip RE
    \return void
    * Postcondition: The BSONObj is updated with source-ip destnation-ip details */

void normSnort::normalize_ip(std::string &input,boost::regex &e)
{
    using namespace std;
    boost::match_results<std::string::const_iterator> what;
    if(0 == boost::regex_search(input, what, e,boost::match_default | boost::match_partial))
    {
          return;
    }
    if(what[0].matched && (what.size()==10))
    {
        x.append("SIP",string(what[2].first,what[2].second));
        x.append("SPort",string(what[4].first,what[4].second));
        x.append("DIP",string(what[6].first,what[6].second));
        x.append("DPort",string(what[9].first,what[9].second));
    }
}
/** \fn void normalize_protocol(string,regex)
    \brief Extract details of protocol from log string
    *Note: Works same like normalize_basic and normalise_ip methods
   */
void normSnort::normalize_protocol(std::string &input,boost::regex &e)
{
    using namespace std;
    boost::match_results<std::string::const_iterator> what;
    if(0 == boost::regex_search(input, what, e,boost::match_default | boost::match_partial))
    {
          return;
    }
    if(what[0].matched && (what.size()==2))
    {
        x.append("Protocol",string(what[1].first,what[1].second));
    }
}
/** \fn BSONObj normalise(string &)
    \brief Common method in all libraries called by the normaliser.
    \param string &input The log string
    \return BSONObj Normalised BSONObject
    */
mongo::BSONObj normSnort::normalise(std::string &input)
{
    /*Normalise each part*/
    normalize_basic(input,b);
    normalize_protocol(input,p);
    normalize_ip(input,i);
    /*Return Object*/
    return x.obj();
}
/*Here's the important task each library has to do WITHOUT FAIL*/
extern "C"{
    /** \fn normaliser *makerSnort()
        \brief This function returns a new object of the specific library
        \param void
        \return normaliser *
        * Note: normaliser is a virtual-class defined in normaliser.hpp and inherited by all library classes
        */
    normaliser * makerSnort()
    {
        return new normSnort;
    }
    /*Create a proxy class which can register the maker function of each library to the factory map present in main.c*/
    class proxyNormSnort
    {
        public:
        proxyNormSnort()
        {
            /*!!IMPORTANT!! "snort" mentioned in the index is the unique tag of this library*/
            factory["snort"]=makerSnort;
        }
    };
    /*An instance of this class will complete the registeration. Refer:self registering objects*/
    proxyNormSnort n;
}

